package com.djzhou.gmms.service.menu.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

import com.djzhou.gmms.model.authority.TbAuthority;
import com.djzhou.gmms.model.entity.PageBean;
import com.djzhou.gmms.model.menu.TbMenu;
import com.djzhou.gmms.model.menu.TbMenuAuthority;
import com.djzhou.gmms.model.menu.TbUserMenuConfig;
import com.djzhou.gmms.model.user.TbUser;
import com.djzhou.gmms.model.user.VoResource;
import com.djzhou.gmms.service.base.impl.BaseServiceImpl;
import com.djzhou.gmms.service.menu.MenuService;
import com.djzhou.util.LevelCodeUtil;

public class MenuServiceImpl extends BaseServiceImpl implements MenuService{

	@Override
	public void add(TbMenu t) {
		menuDAO.insert(t);
		
	}

	@Override
	public void delete(Integer id) {
		TbMenu menu=menuDAO.queryByID(TbMenu.class, id);
		menu.setDeleteFlag(1);
		menuDAO.update(menu);
		
	}

	@Override
	public TbMenu queryById(Integer id) {
		return menuDAO.queryByID(TbMenu.class, id);
	}

	@Override
	public List<TbMenu> queryList(HashMap<String, Object> hashMap) {
		String hql="from TbMenu menu where menu.deleteFlag=0";
		return menuDAO.query(hql);
	}

	@Override
	public PageBean<TbMenu> queryPageBean(HashMap<String, Object> hashMap,
			int pageSize, int currentPage) {
		String departmentId=null;
		String companyId=null;
		String hql="from TbMenu menu where menu.deleteFlag=0";
		StringBuffer sb=new StringBuffer();
		sb.append(hql);
		if(hashMap!=null && hashMap.size()!=0){
			if(hashMap.get("departmentId")!=null){
				departmentId=hashMap.get("departmentId").toString();
				sb.append(" and menu.department.departmentId in (1,").append(departmentId).append(")");
			}
			if(hashMap.get("companyId")!=null){
				companyId=hashMap.get("companyId").toString();
				sb.append(" and (menu.company.companyId=").append(companyId).append(" or menu.company.companyId=1)");
			}
			if(hashMap.get("menuName")!=null){
				companyId=hashMap.get("menuName").toString();
				sb.append(" and menu.menuName like '%").append(hashMap.get("menuName").toString()).append("%'");
			}
		}
		sb.append(" order by backupData desc");
		hql=sb.toString();
		PageBean<TbMenu> pageBean=menuDAO.selectByPage(hql, pageSize, currentPage);
		return pageBean;
	}

	@Override
	public void update(TbMenu t) {
		menuDAO.update(t);
	}

	@Override
	public List<TbMenu> queryMenuListByParentId(Integer parentId,Integer companyId,Integer departmentId,String roleIds) {
		String hql="from TbMenu menu where menu.parentMenuId=? and menu.deleteFlag=0 and menu.openFlag=1 and (menu.company.companyId=? or menu.company.companyId=1) and menu.department.departmentId in (1,?) and (menu.publicMenu=1 or menu.menuId in (select ra.menu.menuId from TbRoleAuthority ra where ra.role.roleId in("+roleIds+")))  order by menu.backupData";
		List<TbMenu> list=menuDAO.query(hql, parentId,companyId,departmentId);
		return list==null?null:list;
	}
	@Override
	public List<TbMenu> queryMenuListByParentId(Integer parentId) {
		String hql="from TbMenu menu where menu.parentMenuId=? and menu.deleteFlag=0 order by menu.backupData";
		List<TbMenu> list=menuDAO.query(hql, parentId);
		return list==null?null:list;
	}

	@Override
	public List<TbMenu> queryList(Integer companyId, Integer departmentId,Integer menuId) {
		String hql="";
		if(companyId!=1){
			hql="from TbMenu menu where menu.deleteFlag=0 and menu.openFlag=1 and menu.publicMenu=0 and (menu.company.companyId=? or menu.company.companyId=1) and menu.department.departmentId in (1,?) and menu.menuId<>? order by menu.backupData";
		}else{
			hql="from TbMenu menu where menu.deleteFlag=0 and menu.openFlag=1 and menu.publicMenu=0 and (menu.company.companyId=? or menu.company.companyId=1) and menu.department.departmentId in (1,?) and menu.menuId<>? order by menu.backupData";
		}
		return menuDAO.query(hql,companyId,departmentId,menuId);
	}
	
	@Override
	public List<TbMenu> queryListForAction(Integer companyId, Integer departmentId,Integer menuId) {
		String hql="";
		if(companyId!=1){
			hql="from TbMenu menu where menu.deleteFlag=0 and (menu.company.companyId=? or menu.company.companyId=1) and menu.department.departmentId in (1,?) and menu.menuId<>? order by menu.backupData";
		}else{
			hql="from TbMenu menu where menu.deleteFlag=0 and (menu.company.companyId=? or menu.company.companyId=1) and menu.department.departmentId in (1,?) and menu.menuId<>? order by menu.backupData";
		}
		return menuDAO.query(hql,companyId,departmentId,menuId);
	}
	
	@Override
	public void updateSortMenu(String sortMenuIds,int parentMenuId){
		String ids[] = sortMenuIds.split(",");
		LevelCodeUtil util =new LevelCodeUtil();
		String parentCode = parentMenuId==0 ? "" : menuDAO.queryLevelCodeById(parentMenuId);
		for(int i=0;i<ids.length;i++){
			String id = ids[i];
			String order = parentCode+util.formatLevelCode((i+1)+"");
			menuDAO.updateForSpring("update TbMenu set backupData='"+order+"' where menuId="+id);
			if(parentMenuId==0){
				//修改子菜单的排序，目前只支持2级菜单
				List<TbMenu> child = queryMenuListByParentId(Integer.parseInt(id));
				for(int j = 0; j< child.size();j++){
					TbMenu cm = child.get(j);
					cm.setBackupData(order+util.formatLevelCode((j+1)+""));
					update(cm);
				}
			}
		}
		return;
	}
	
	public void updateResetAllMenuLevelCode(){
		//重置排序字段，目前只支持2级菜单，可以扩展成无限制
		/**********************************为了效率现在只支持2级菜单，如果放开菜单务必要修改此方法***************************************/
		List<TbMenu> list = queryMenuListByParentId(0);
		LevelCodeUtil util =new LevelCodeUtil();
		for(int i = 0; i< list.size();i++){
			TbMenu m = list.get(i);
			m.setBackupData(util.formatLevelCode((i+1)+""));
			update(m);
			List<TbMenu> child = queryMenuListByParentId(m.getMenuId());
			for(int j = 0; j< child.size();j++){
				TbMenu cm = child.get(j);
				cm.setBackupData(m.getBackupData()+util.formatLevelCode((j+1)+""));
				update(cm);
			}
		}
	}

	@Override
	public void add(TbMenu menu, String authorityString) {
		//获取排序字段
		if(menu.getMenuOrder()==null || menu.getMenuOrder().equals("")){
			//获取层级编码
			menu.setBackupData(queryLevelCodeByParentId(menu.getParentMenuId()));
		}else{
			//修改该菜单之后的菜单层级
			List<TbMenu> after = menuDAO.query("from TbMenu where parentMenuId="+menu.getParentMenuId()+" and backupData >='"+menu.getMenuOrder()+"' order by backupData");
			LevelCodeUtil util = new LevelCodeUtil();
			int length = after.size()-1;
			for(int i = length;i>-1;i--){
				String order = after.get(i).getBackupData();
				if(i==length && order.substring(order.length()-LevelCodeUtil.codeLength).equals(util.maxLevel()+"")){
					//超过最大，重置排序，重新赋值
					updateResetAllMenuLevelCode();
					menu.setMenuOrder(menuDAO.queryLevelCodeById(menu.getAfterMenuId()));
					add(menu,authorityString);
					return;
				}
				String newOrder =order.substring(0,order.length()-LevelCodeUtil.codeLength)+util.formatLevelCode((Integer.parseInt(order.substring(order.length()-LevelCodeUtil.codeLength))+1)+"");
				menuDAO.updateForSpring("update TbMenu set backupData = '"+newOrder+"' + substring(backupData,"+(newOrder.length()+1)+",length(backupData)) where backupData like '"+order+"%'");
			}
			menu.setBackupData(menu.getMenuOrder());
		}
		menuDAO.insert(menu);
		TbUser user=menu.getUser();
		String[] array=authorityString.split(" ");
		for(String str:array){
			TbMenuAuthority menuAuthority=new TbMenuAuthority();
			TbAuthority authority=authorityDAO.queryByID(TbAuthority.class, Integer.parseInt(str));
			menuAuthority.setAuthority(authority);
			menuAuthority.setCreateTime(new Date());
			menuAuthority.setDeleteFlag(0);
			menuAuthority.setLastModifyTime(new Date());
			menuAuthority.setMenu(menu);
			menuAuthority.setRemark("");
			menuAuthority.setUser(user); 
			menuAuthorityDAO.insert(menuAuthority);
		}
	}
	
	@Override
	public String queryLevelCodeByParentId(Integer parentMenuId){
		String result = menuDAO.queryLevelCodeByParentId(parentMenuId);
		if(result.equals("-1")){
			//已经满了
			updateResetAllMenuLevelCode();
			result = menuDAO.queryLevelCodeByParentId(parentMenuId);
		}
		return result;
	}

	@Override
	public void update(TbMenu menu, String authorityString) {
		//位置发生变动
		if(!menu.getBackupData().equals(menu.getMenuOrder())){
			//获取排序字段
			if(menu.getMenuOrder()==null || menu.getMenuOrder().equals("")){
				//获取层级编码
				String newOrder = queryLevelCodeByParentId(menu.getParentMenuId());
				menuDAO.updateForSpring("update TbMenu set backupData = '"+newOrder+"' + substring(backupData,"+(newOrder.length()+1)+",length(backupData)) where backupData like '"+menu.getBackupData()+"%'");
				menu.setBackupData(newOrder);
			}else{
				//把子菜单都置为临时
				String temp = "";
				//修改该菜单之后的菜单层级
				List<TbMenu> after = menuDAO.query("from TbMenu where menuId<> "+menu.getMenuId()+" and parentMenuId="+menu.getParentMenuId()+" and backupData >='"+menu.getMenuOrder()+"' order by backupData");
				LevelCodeUtil util = new LevelCodeUtil();
				int length = after.size()-1;
				for(int i = length;i>-1;i--){
					String order = after.get(i).getBackupData();
					if(i==length){
						if(order.substring(order.length()-LevelCodeUtil.codeLength).equals(util.maxLevel()+"")){
							//超过最大，重置排序，重新赋值
							updateResetAllMenuLevelCode();
							menu.setMenuOrder(menuDAO.queryLevelCodeById(menu.getAfterMenuId()));
							menu.setBackupData(menuDAO.queryLevelCodeById(menu.getMenuId()));
							update(menu,authorityString);
							return;
						}else{
							for(int j = 0;j<menu.getMenuOrder().length();j++){
								temp+="-";
							}
							menuDAO.updateForSpring("update TbMenu set backupData = '"+temp+"' + substring(backupData,"+(temp.length()+1)+",length(backupData)) where backupData like '"+menu.getBackupData()+"%'");
						}
					}
					String newOrder =order.substring(0,order.length()-LevelCodeUtil.codeLength)+util.formatLevelCode((Integer.parseInt(order.substring(order.length()-LevelCodeUtil.codeLength))+1)+"");
					menuDAO.updateForSpring("update TbMenu set backupData = '"+newOrder+"' + substring(backupData,"+(newOrder.length()+1)+",length(backupData)) where backupData like '"+order+"%'");
				}
				String newOrder = menu.getMenuOrder();
				menuDAO.updateForSpring("update TbMenu set backupData = '"+newOrder+"' + substring(backupData,"+(newOrder.length()+1)+",length(backupData)) where backupData like '"+temp+"%'");
				menu.setBackupData(newOrder);
			}
		}
		menuDAO.merge(menu);
		Integer menuId=menu.getMenuId();
		menuDAO.updateForSpring("delete from TbMenuAuthority ma where ma.menu.menuId =?", menuId);
		TbUser user=menu.getUser();
		String[] array=authorityString.split(" ");
		for(String str:array){
			TbMenuAuthority menuAuthority=new TbMenuAuthority();
			TbAuthority authority=authorityDAO.queryByID(TbAuthority.class, Integer.parseInt(str));
			menuAuthority.setAuthority(authority);
			menuAuthority.setCreateTime(new Date());
			menuAuthority.setDeleteFlag(0);
			menuAuthority.setLastModifyTime(new Date());
			menuAuthority.setMenu(menu);
			menuAuthority.setRemark("");
			menuAuthority.setUser(user); 
			menuAuthorityDAO.insert(menuAuthority);
		}
		
	}
	@Override
	public VoResource query4AutoComplete(HashMap<String, Object> hashMap, String sidx,
			String sord, int pageSize, int currentPage) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public List<TbMenu> queryHistoryMenuList(String menuIds) {
		String hql="from TbMenu where menuId in("+menuIds+")";
		return menuDAO.query(hql);
	}

	@Override
	public List<TbMenu> queryApps(Integer companyId, Integer departmentId,
			String roleIds) {
		String hql="from TbMenu menu where menu.parentMenuId<>0 and menu.deleteFlag=0 and menu.openFlag=1 and (menu.company.companyId=? or menu.company.companyId=1) and menu.department.departmentId in (1,?) and (menu.publicMenu=1 or menu.menuId in (select ra.menu.menuId from TbRoleAuthority ra where ra.role.roleId in("+roleIds+")))  order by menu.backupData";
		List<TbMenu> list=menuDAO.query(hql,companyId,departmentId);
		return list==null?null:list;
	}

	@Override
	public List<TbUserMenuConfig> queryOftenApps(Integer userId,Integer companyId, Integer departmentId,
			String roleIds) {
		String hql="from TbUserMenuConfig umc where umc.showApps=1 and umc.user.userId=? and umc.menu.menuId in (select menu.menuId from TbMenu menu where menu.parentMenuId<>0 and menu.deleteFlag=0 and menu.openFlag=1 and (menu.company.companyId=? or menu.company.companyId=1) and menu.department.departmentId in (1,?) and (menu.publicMenu=1 or menu.menuId in (select ra.menu.menuId from TbRoleAuthority ra where ra.role.roleId in("+roleIds+")))) order by umc.menuOrder asc";
		List<TbUserMenuConfig> list=userMenuConfigDAO.query(hql,userId,companyId,departmentId);
		return list==null?null:list;
	}
}
